import Vue from "vue";
import VueRouter from "vue-router";
import routes from "./routes";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import store from "@/store";

Vue.use(VueRouter);

//重写编程式路由导航的push 和 replace
const oldPush = VueRouter.prototype.push;
VueRouter.prototype.push = function (
  loaction,
  onComplate = () => {},
  onAbort = () => {}
) {
  oldPush.call(this, loaction, onComplate, onAbort);
};

const oldReplace = VueRouter.prototype.replace;
VueRouter.prototype.replace = function (
  loaction,
  onComplate = () => {},
  onAbort = () => {}
) {
  oldReplace.call(this, loaction, onComplate, onAbort);
};

const router = new VueRouter({
  mode: "history",
  routes,
  scrollBehavior() {
    return { x: 0, y: 0 };
  },
});

/* 
    路由鉴权全过程
  判断有没有token
    有token
      判断有没有用户信息
      如果有,则说明用户刚刚拿token请求了数据,token是没有问题的,则直接放行

      如果没有,则不确定token到底管不管用,我们需要发送一个请求,请求用户信息
      如果请求成功,则说明token没有问题,直接放行
      如果请求失败,则说明token可能有问题了,则清空当前的token,并跳转到login页重新登录


    没有token
      判断要去的页面在不在白名单中
      如果在白名单中就放行
      如果不在白名单中 就跳转到login页 重新登录
*/

//全局前置守卫
router.beforeEach(async (to, from, next) => {
  const token = store.state.user.token; // 拿到vuex中的token
  const nickName = store.state.user.userInfo.nickName; // 获取vuex中的用户信息
  console.log(nickName);
  NProgress.start();

  if (token) {
    // 如果能够进入这个if 则说明什么？
    // 此时 说明用户一定登录过 但是token有没有过期 我们是不确定的
    if (to.name === "Login") {
      next("/home");
      if (from.name === "Home") NProgress.done();
    }
    // 这个时候才是做token校验 路由鉴权的重点时候
    if (nickName) {
      // 如果能够进入这个if 则说明此时 token一定是有用的 用户信息也是有用的 token没有过期
      console.log(4);
      // 所以我们要无条件放行
      next();
    } else {
      // 如果没有用户信息 进入这个else 说明token过期了
      console.log(5);
      try {
        // dispath 的返回值 是一个promise
        await store.dispatch("user/getUserInfo"); // 获取用户信息请求
        // 无条件放行
        next();
      } catch (e) {
        store.commit("user/clear_Token");
        next(`/login?to=${to.name}`);
      }
    }
  } else {
    // 如果能够进入这个else 则说明 用户是没有登录过的 没有token
    // 这里面一般做的是黑白名单的判断
    if (to.meta.isAuth) {
      next(`/login?to=${to.name}`);
    } else {
      next();
    }
  }
});

//全局后置钩子
router.afterEach(() => {
  NProgress.done();
});

export default router;
